#include <terminal.h>
#include <logbase.h>
#include <uart.h>
#include <wdg.h>
static char DEV_C51_XDATA_FLAG tmnPsBuf[128];
static termParseStc DEV_C51_XDATA_FLAG *tmnPsPtr = (termParseStc *)tmnPsBuf;
void tmnPsInit()
{
    tmnPsPtr->parseStep = 0;
    tmnPsPtr->packSize = sizeof(tmnPsBuf) - offsetof(termParseStc, packData);
    tmnPsPtr->rcvSize = 0;
}
void tmnDealCmd(char *instr);
void tmnPsUp()
{
    uint8_t indata;
    if (uartRcvStr_1(&indata, 1) < 1)
    {
        return;
    }
    switch (indata)
    {
    case '\b':// delete
    {
        if (tmnPsPtr->rcvSize > 0)
        {
            tmnPsPtr->rcvSize--;
        }
        else
        {
            break;
        }
        logSndByte(0x08);
        logSndByte(0x1b);
        logSndByte(0x5b);
        logSndByte(0x4a);
        break;
    }
    case '\r':
    {
        logSndStr("\n", 1);
        if (tmnPsPtr->rcvSize > 0)
        {
            // logHexBuf("", &tmnPsPtr->rcvSize, 1);
            // logHexBuf("", tmnPsPtr->packData, tmnPsPtr->rcvSize);
            // logdebugc("%s", tmnPsPtr->packData);
            tmnDealCmd(tmnPsPtr->packData);
        }
        logSndStr("# ", 2);
        // logSndStr("\n# ", 3);
        tmnPsPtr->rcvSize = 0;
        memset(tmnPsPtr->packData, 0, tmnPsPtr->packSize);
        break;
    }
    case 0x1b: // drop key(<-(left), ->(right), -^(up), -(down))
    {
        uartRcvStr_1(&indata, 1);
        uartRcvStr_1(&indata, 1);
        // if (uartRcvStr_1(&indata, 1) < 0)
        // {
        //     logdebugc("rcv error1?");
        //     break;
        // }
        // if (uartRcvStr_1(&indata, 1) < 0)
        // {
        //     logdebugc("rcv error2?");
        //     break;
        // }
        break;
    }
    default:
    {
        if (tmnPsPtr->rcvSize < tmnPsPtr->packSize)
        {
            tmnPsPtr->packData[tmnPsPtr->rcvSize++] = indata;
        }
        else
        {
            break;
        }
        logSndByte(indata);
        break;
    }
    }
}

// if not use 51, function can use callback function into tmnCmdList
void termCmd_help(char *dataptr)
{
    logdebugc("terminal cmd list:");
    logdebugc("help    : show cmd list");
    logdebugc("ls      : check ls cmd");
    logdebugc("reboot  : reboot cmd");
    logdebugc("stop    : stop run,check watchdog");
    dataptr = NULL;
}
void termCmd_ls(char *dataptr)
{
    char *tmpPtr;
    uint8_t tmpid = 1;
    if (!(dataptr && dataptr[0] != '\0'))
    {
        logdebugc("has no parm");
        return;
    }
    do
    {
        tmpPtr = strchr(dataptr, ' ');
        if (!tmpPtr)
        {
            logdebugc("in parm%d:%s", (uint16_t)tmpid++, dataptr);
            break;
        }
        else
        {
            tmpPtr[0] = '\0';
            logdebugc("in parm%d:%s", (uint16_t)tmpid++, dataptr);
            dataptr = tmpPtr + 1;
        }
    } while (1);
}
void termCmd_reboot(char *dataptr)
{
    logdebugc("do reboot");
    dataptr = NULL;
    stcReboot();
}
void termCmd_stop(char *dataptr)
{
    logdebugc("do stop");
    dataptr = NULL;
    while(1);
}

void tmnDealCmd(char *instr)
{
    char *dataptr = NULL;
    int cmdlen;
    dataptr = strchr(instr, ' ');
    if (dataptr)
    {
        cmdlen = dataptr - instr;
        *dataptr = '\0';
        dataptr++;
    }
    else
    {
        cmdlen = strlen(instr);
        // instr[cmdlen] = 0;
    }
    if (cmdlen <= 0)
    {
        logdebugc("not input!");
        return;
    }
    logdebugc("input:%s,cmdlen=%d,data=%s", instr, cmdlen, dataptr);
    if (strcmp(instr, "help") == 0)
    {
        termCmd_help(dataptr);
    }
    else if (strcmp(instr, "ls") == 0)
    {
        termCmd_ls(dataptr);
    }
    else if (strcmp(instr, "reboot") == 0)
    {
        termCmd_reboot(dataptr);
    }
    else if (strcmp(instr, "stop") == 0)
    {
        termCmd_stop(dataptr);
    }
    else
    {
        logdebugc("unknow cmd:%s, use help", instr);
    }
}
